﻿using System;
using System.Linq;
using System.Text;
using System.Web;
using Web.Base.Security;
using System.Collections;
using Web.Base.Components;
using Ayatta.Contract.Domain;
using System.Security.Principal;
using System.Collections.Generic;

namespace Web.Base.Models
{
    public enum ShoppingCartOperate
    {
        UpdateQuantity = 0,
        Remove = 1,
        Clear = 2
    }
    public sealed class ShoppingCart
    {
        public static string SessionKey = "shoppingcart";
        private readonly Hashtable cartItems = Hashtable.Synchronized(new Hashtable());
        public static readonly ShoppingCartConfig Config = new ShoppingCartConfig(false, false);

        /// <summary>
        /// 用户
        /// </summary>
        public IIdentity Identity { get { return HttpContext.Current.User.Identity; } }
        /// <summary>
        /// 商品总数量
        /// </summary>
        public int Quantity { get { return Items.Sum(o => o.Quantity); } }
        /// <summary>
        /// 商品总重量
        /// </summary>
        public decimal Weight { get { return Items.Sum(o => o.Weight); } }
        /// <summary>
        /// 商品总折扣
        /// </summary>
        public decimal Discount { get { return ShippingDiscounts.Sum(o => o.Value) + OrderSubTotalDiscounts.Sum(o => o.Value) + OrderTotalDiscounts.Sum(o => o.Value); } }
        /// <summary>
        /// 商品总金额
        /// </summary>
        public decimal SubTotal { get { return Items.Sum(o => o.Quantity * o.Price-o.Discount); } }
        /// <summary>
        /// 订单总金额
        /// </summary>
        public decimal Total { get { return SubTotal + ShippingCharge - Discount; } }

        /// <summary>
        /// 运输费
        /// </summary>
        public decimal ShippingCharge { get; set; }

        public IDictionary<int, decimal> OrderSubTotalDiscounts { get; set; }
        public IDictionary<int, decimal> OrderTotalDiscounts { get; set; }
        public IDictionary<int, decimal> ShippingDiscounts { get; set; }

        public UserAddress UserAddress { get; set; }
        public UserInvoice UserInvoice { get; set; }
        public IList<ShoppingCartItem> Items { get { return cartItems.Values.Cast<ShoppingCartItem>().ToList(); } }

        public ShoppingCart()
        {
            UserInvoice = new UserInvoice();
            ShippingDiscounts = new Dictionary<int, decimal>();
            OrderTotalDiscounts = new Dictionary<int, decimal>();
            OrderSubTotalDiscounts = new Dictionary<int, decimal>();
        }

        public void Add(ShoppingCartItem cartItem)
        {
            if (cartItem == null) return;
            var itemId = cartItem.Id;
            var skuId = cartItem.SkuId;
            var key = string.Format("{0}:{1}", itemId, skuId);

            if (cartItems.ContainsKey(key))
            {
                var temp = cartItems[key] as ShoppingCartItem;
                if (temp != null)
                {
                    if (temp.Quantity >= temp.OrderMaxQuantity)
                    {
                        temp.Message = string.Format("一个订单中最多只能购买{0}个", temp.OrderMaxQuantity);
                    }
                    else
                    {
                        temp.Message = string.Empty;
                        temp.Quantity += cartItem.Quantity;
                    }
                }
            }
            else
            {
                cartItems.Add(key, cartItem);
            }
        }

        public void Remove(int itemId, int skuId)
        {
            var key = string.Format("{0}:{1}", itemId, skuId);
            var temp = cartItems[key] as ShoppingCartItem;
            if (temp == null) return;
            cartItems.Remove(key);
        }

        public void UpdateQuantity(int itemId, int skuId, int quantity)
        {
            var key = string.Format("{0}:{1}", itemId, skuId);
            if (quantity < 1)
            {
                cartItems.Remove(key);
                return;
            }
            var temp = cartItems[key] as ShoppingCartItem;
            if (temp == null) return;

            if (quantity >= temp.OrderMaxQuantity)
            {
                temp.Quantity = temp.OrderMaxQuantity;
                temp.Message = string.Format("一个订单中最多只能购买{0}个", temp.OrderMaxQuantity);
            }
            else
            {
                temp.Quantity = quantity;
                temp.Message = string.Empty;
            }
        }

        public MiniCart ToMiniCart()
        {
            var items = Items.Select(o => new MiniCartItem { }).ToList();
            var miniCart = new MiniCart(Quantity, SubTotal, items);
            return miniCart;
        }

        public Order ToOrder(string ipAddress)
        {
            var order = new Order();
            var time = DateTime.Now;
            var identity = Identity.Identity();
            var orderId = GenerateOrderId(time, identity.Id);
            var shippingType=ShippingType.Express;
            if (Items.All(o => o.IsVirtual))
            {
                shippingType = ShippingType.Virtual;
            }
            order.Id = orderId;
            order.Category = 0;
            order.Quantity = Quantity;
            order.Postage = ShippingCharge;
            order.SubTotal = SubTotal;
            order.Discount = Discount;
            order.Total = Total;
            order.Paid = 0;
            order.UseIntegral = 0;
            order.RealUseIntegral = 0;
            order.DonateIntegral = 0;
            order.Weight = 0;
            order.PaymentType = PaymentType.None;
            order.ShippingType = shippingType;
            order.PaymentType = 0;
            order.PayTime = null;
            order.ConsignTime = null;
            order.EndTime = null;
            order.ExpirationTime = time.AddDays(2);
            order.ETicketExtra = string.Empty;
            order.MultipleConsign = false;
            order.Receiver = UserAddress.Name;
            order.Phone = UserAddress.Phone;
            order.Mobile = UserAddress.Mobile;
            order.AreaId = UserAddress.AreaId;
            order.Province = UserAddress.Province;
            order.City = UserAddress.City;
            order.District = UserAddress.District;
            order.Address = UserAddress.Address;
            order.PostalCode = UserAddress.PostalCode;
            order.InvoiceCategory = string.Empty;
            order.HasInvoice = false;
            order.InvoiceTitle = string.Empty;
            order.InvoiceContent = string.Empty;
            order.IpAddress = ipAddress;
            order.TraceCode = string.Empty;
            order.AssociatedId = string.Empty;
            order.BuyerId = identity.Id;
            order.BuyerNick = identity.NickName;
            order.BuyerFlag = 0;
            order.BuyerMemo = string.Empty;
            order.BuyerMessage = string.Empty;
            order.BuyerRate = false;
            order.SellerId = 0;
            order.SellerNick = string.Empty;
            order.SellerFlag = 0;
            order.SellerMemo = string.Empty;
            order.SellerRate = false;
            order.Status = OrderStatus.Pending;
            order.Extra = string.Empty;
            order.ModifiedOn = time;
            order.CreatedBy = Identity.Name;
            order.CreatedOn = time;


            var items = Items.Select((o, i) =>
                                     new OrderItem {
                                         Id = orderId + i.ToString("00"),
                                         OrderId = orderId,
                                         SkuId = o.SkuId,
                                         ItemId = o.Id,
                                         ProductId = 0,
                                         CategoryId = 0,
                                         CategoryRootId = 0,
                                         OuterId = string.Empty,
                                         MealId = 0,
                                         MealName = string.Empty,
                                         Title = o.Name,
                                         PictureUrl = string.Empty,
                                         Properties = o.GetPropsName(),
                                         Quantity = o.Quantity,
                                         Price = o.Price,
                                         Discount = o.Discount,
                                         Adjust = 0,
                                         Total = o.Total,
                                         Paid = 0,
                                         ShippingType = 0,
                                         BuyerId = identity.Id,
                                         SellerId = 0,
                                         IsGift = false,
                                         IsService = false,
                                         IsVirtual=o.IsVirtual,
                                         EndTime = null,
                                         ExpirationTime = time.AddDays(3),
                                         BindId = string.Empty,
                                         ShippingCompany = string.Empty,
                                         ExpressNo = string.Empty,
                                         ConsignTime = null,
                                         Status = OrderStatus.WaitBuyerPay,
                                         Extra = string.Empty,
                                         ModifiedOn = time,
                                         CreatedBy = Identity.Name,
                                         CreatedOn = time
                                     });
            order.OrderItems = items.ToList();
            return order;
        }

        private static string GenerateOrderId(DateTime time, int userId, int supplierId = 0)
        {
            var sb = new StringBuilder(4);
            sb.Append("A");
            sb.Append(time.ToString("yyMMddHHmmssfffffff"));
            sb.Append(userId.ToString("00"));
            sb.Append(supplierId.ToString("00"));
            return sb.ToString();
        }

        //private static string GenerateOrderId(DateTime time)
        //{
        //    var array = new[] { '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V' };
        //    var year = time.ToString("yy");
        //    var month = array[time.Month - 1];
        //    var day = array[time.Day - 1];
        //    var hour = array[time.Hour - 1];
        //    var minute = time.ToString("mm");
        //    var second = time.ToString("ss");
        //    var ticks = time.ToString("fffffff");
        //    return year + month + day + hour + minute + second + ticks;
        //}
    }
}